package com.generator;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

import com.operation.Add;
import com.operation.Divide;
import com.operation.Multiply;
import com.operation.Operation;
import com.operation.Subtract;

public class QuestionGenerator {
    private Scanner scanner;  // 由外部传入
    private Random random = new Random();
    private List<Question> questionList;

    // 新增构造方法：接收外部的Scanner实例
    public QuestionGenerator(Scanner scanner) {
        this.scanner = scanner;
    }

    public List<Question> generateQuestions() {
        // 1. 获取用户选择的运算类型
        Operation targetOperation = selectOperationType();
        // 2. 获取用户选择的运算数个数（2或3）
        int numCount = selectNumberCount();
        // 3. 获取用户选择的题目数量
        int questionCount = selectQuestionCount();
        // 4. 初始化题目列表
        questionList = new ArrayList<>(questionCount);
        // 5. 生成题目（根据运算数个数分支）
        if (numCount == 2) {
            generateTwoNumQuestions(targetOperation, questionCount);
        } else if (numCount == 3) {
            generateThreeNumQuestions(questionCount);
        }
        return questionList;
    }

    /**
     * 步骤1：让用户选择运算类型（1-7）
     * @return 对应的运算实例（如Add、Divide）
     */
    private Operation selectOperationType() {
        Operation operation = null;
        while (operation == null) {
            System.out.println("===== 选择运算类型 =====");
            System.out.println("1-纯加法  2-纯减法  3-纯乘法  4-纯除法");
            System.out.println("5-加减法混合  6-乘除法混合  7-3数加减乘除混合");
            System.out.print("请输入选择（1-7）：");
            int choice = scanner.nextInt();
            switch (choice) {
                case 1:
                    operation = new Add();
                    break;
                case 2:
                    operation = new Subtract();
                    break;
                case 3:
                    operation = new Multiply();
                    break;
                case 4:
                    operation = new Divide();
                    break;
                case 5:
                    operation = new MixedAddSub(); // 自定义混合运算类（见下方）
                    break;
                case 6:
                    operation = new MixedMulDiv(); // 自定义混合运算类（见下方）
                    break;
                case 7:
                    // 3数混合运算无需指定单一运算，返回null即可（后续单独处理）
                    return null;
                default:
                    System.out.println("输入错误！请重新选择（1-7）");
            }
        }
        return operation;
    }

    /**
     * 步骤2：让用户选择运算数个数（2或3）
     * @return 2或3
     */
    private int selectNumberCount() {
        int numCount = 0;
        while (numCount != 2 && numCount != 3) {
            System.out.print("\n请选择运算数个数（2或3）：");
            numCount = scanner.nextInt();
            if (numCount != 2 && numCount != 3) {
                System.out.println("输入错误！仅支持2或3个运算数");
            }
        }
        return numCount;
    }

    /**
     * 步骤3：让用户选择生成题目数量（≥1）
     * @return 题目数量（如30、50）
     */
    private int selectQuestionCount() {
        int count = 0;
        while (count <= 0) {
            System.out.print("\n请输入生成题目数量（≥1）：");
            count = scanner.nextInt();
            if (count <= 0) {
                System.out.println("输入错误！题目数量需≥1");
            }
        }
        return count;
    }

    /**
     * 生成2数运算题目（纯运算或2数混合运算）
     * @param operation 运算类型（如Add、MixedAddSub）
     * @param count 题目数量
     */
    private void generateTwoNumQuestions(Operation operation, int count) {
        int generated = 0; // 已生成的有效题目数量
        while (generated < count) {
            // 生成1-99的随机运算数（实验约束：参与数据>0且<100）
            int a = random.nextInt(98) + 1; // nextInt(98)生成0-97，+1后1-98？不，98+1=99，正确
            int b = random.nextInt(98) + 1;
            try {
                // 调用运算类的calculate方法，若抛异常则跳过当前题目
                int answer = operation.calculate(a, b);
                // 生成题目字符串（如"a+b="）
                String questionStr = a + operation.getOperator() + b + "=";
                // 添加到题目列表
                questionList.add(new Question(questionStr, answer));
                generated++; // 仅有效题目计数+1
            } catch (IllegalArgumentException e) {
                // 运算不符合约束（如减法结果≤0），跳过当前题目，重新生成
                continue;
            }
        }
    }

    /**
     * 生成3数加减乘除混合运算题目（需保证中间结果和最终结果符合约束）
     * @param count 题目数量
     */
    private void generateThreeNumQuestions(int count) {
        int generated = 0;
        while (generated < count) {
            // 生成3个1-99的随机运算数
            int a = random.nextInt(98) + 1;
            int b = random.nextInt(98) + 1;
            int c = random.nextInt(98) + 1;
            // 随机选择两个运算（op1：a与b的运算，op2：中间结果与c的运算）
            Operation op1 = getRandomOperation();
            Operation op2 = getRandomOperation();
            try {
                // 第一步：计算a op1 b的中间结果，需符合约束
                int midResult = op1.calculate(a, b);
                // 第二步：计算中间结果 op2 c的最终结果，需符合约束
                int finalResult = op2.calculate(midResult, c);
                // 生成3数题目字符串（如"a+ b×c="）
                String questionStr = a + op1.getOperator() + b + op2.getOperator() + c + "=";
                questionList.add(new Question(questionStr, finalResult));
                generated++;
            } catch (IllegalArgumentException e) {
                // 中间结果或最终结果不符合约束，重新生成
                continue;
            }
        }
    }

    /**
     * 辅助方法：随机获取一个运算实例（用于混合运算）
     * @return 随机的运算实例（Add/Subtract/Multiply/Divide）
     */
    private Operation getRandomOperation() {
        int type = random.nextInt(4); // 0-3对应4种基础运算
        switch (type) {
            case 0:
                return new Add();
            case 1:
                return new Subtract();
            case 2:
                return new Multiply();
            case 3:
                return new Divide();
            default:
                return new Add();
        }
    }

    // ---------------------- 自定义混合运算类（内部类） ----------------------
    /**
     * 加减法混合运算类：随机选择加法或减法
     */
    private class MixedAddSub extends Operation {
        private Random random = new Random();

        @Override
        public int calculate(int a, int b) throws IllegalArgumentException {
            // 50%概率选择加法，50%选择减法
            if (random.nextBoolean()) {
                return new Add().calculate(a, b);
            } else {
                return new Subtract().calculate(a, b);
            }
        }

        @Override
        public String getOperator() {
            // 需与calculate的运算类型匹配，因此重新随机一次（或存储运算类型，此处简化）
            return random.nextBoolean() ? "+" : "-";
        }
    }

    /**
     * 乘除法混合运算类：随机选择乘法或除法
     */
    private class MixedMulDiv extends Operation {
        private Random random = new Random();
        private String currentOperator; // 存储当前运算符号，确保与calculate匹配

        @Override
        public int calculate(int a, int b) throws IllegalArgumentException {
            if (random.nextBoolean()) {
                currentOperator = "×";
                return new Multiply().calculate(a, b);
            } else {
                currentOperator = "÷";
                return new Divide().calculate(a, b);
            }
        }

        @Override
        public String getOperator() {
            return currentOperator;
        }
    }
}